// ast 语法树 抽象语法树 是用对象  来描述语法的、

const ncname = `[a-zA-Z_][\\-\\.0-9_a-zA-Z]*`
const qnameCapture = `((?:${ncname}\\:)?${ncname})`
const startTagOpen = new RegExp(`^<${qnameCapture}`);
// let r = '<a.b:b.a>xxxx'.match(startTagOpen)
// console.log(r)
const endTag = new RegExp(`^<\\/${qnameCapture}[^>]*>`);
// 匹配属性的 
const attribute = /^\s*([^\s"'<>\/=]+)(?:\s*(=)\s*(?:"([^"]*)"+|'([^']*)'+|([^\s"'=<>`]+)))?/;
// console.log('id="xxx"'.match(attribute))
// 匹配标签结束的
const startTagClose = /^\s*(\/?)>/;
// 花括号 
const defaultTagRE = /\{\{((?:.|\r?\n)+?)\}\}/g;




// 解析html字符串
export function parseHTML(html) {
  let root = null; // ast语法树树根
  let currentParent; // 
  let stack = []
  const ELEMENT_TYPE = 1;
  const TEXT_TYPE = 3;

  function createASTElement(tagName, attrs) {
    return {
      tag: tagName,
      type: ELEMENT_TYPE,
      children: [],
      attrs,
      parent: null
    }
  }



  function start(tagName, attrs) {
    // console.log('开始标签', tagName, attrs)
    // 开始的时候 就创建一个ast元素
    let element = createASTElement(tagName, attrs);
    if (!root) {
      root = element
    }
    currentParent = element
    stack.push(element)
  }
  function end(tagName) {
    // console.log('结束标签', tagName)
    let element = stack.pop()
    currentParent = stack[stack.length - 1]
    if (currentParent) {
      element.parent = currentParent
      currentParent.children.push(element)
    }
  }
  function chars(text) {
    text = text.replace(/\s/g, '')
    if (text) {
      currentParent.children.push({
        text,
        type: TEXT_TYPE,

      })
    }
    // console.log('文本是', text)
  }
  while (html) {
    let textEnd = html.indexOf('<')
    if (textEnd == 0) {
      let startTagMatch = parseStartTag(); // 通过这个 方法 获取到 匹配的结果 tagName attrs
      if (startTagMatch) {
        start(startTagMatch.tagName, startTagMatch.attrs)
        continue
      }
      let endTagMatch = html.match(endTag)
      if (endTagMatch) {
        advance(endTagMatch[0].length)
        end(endTagMatch[1])
        continue
      }

    }
    let text;
    if (textEnd >= 0) {
      text = html.substring(0, textEnd)
    }
    if (text) {
      advance(text.length)
      chars(text)
    }
    // break
  }
  console.log('root', root)
  return root
  // 每解析一段 就删一段
  function advance(n) {
    html = html.substring(n)
  }
  function parseStartTag() {
    let start = html.match(startTagOpen)
    if (start) {
      const match = {
        tagName: start[1],
        attrs: []
      }
      advance(start[0].length)
      let end, attr;
      // 这个是取出属性
      while (!(end = html.match(startTagClose)) && (attr = html.match(attribute))) {
        advance(attr[0].length)
        match.attrs.push({ name: attr[1], value: attr[3] || attr[4] || attr[5] || attr })
      }
      // console.log(match, html)
      if (end) {
        advance(end[0].length)
        return match
      }
    }

  }
}

